"""
睡眠分析会话模型 - 频域比例累积存储模式

本文件定义了支持频域比例累积数据存储的睡眠分析会话模型，主要用于：
1. 一次会话对应一条数据库记录
2. 每次有新数据时更新现有记录，将新的频域比例数据按照时间戳增加进去
3. 支持按时间戳排序的睡眠分期和频域比例数据存储
4. 提供会话统计信息和数据质量指标

主要模型：
- FrequencyAnalysisPoint: 单个频域分析数据点模型（对应frequency_analysis_data数组中的元素）
- SleepAnalysisSession: 睡眠分析会话主模型
- SessionCreateRequest: 创建会话请求模型
- SessionUpdateRequest: 更新会话数据请求模型
- SessionQueryResponse: 会话查询响应模型

数据存储原理：
使用JSON字段存储frequency_analysis_data数组，每个数组元素包含时间戳、睡眠分期结果和5个频域比例数据。
通过累积更新模式，避免频繁创建新记录，提高数据库性能和查询效率。
支持会话级别的睡眠分析统计信息计算和数据质量评估。
"""

from typing import List, Optional, Dict, Any
from pydantic import BaseModel, Field, validator
from datetime import datetime
from enum import Enum


class SessionStatus(str, Enum):
    """会话状态枚举"""
    ACTIVE = "active"
    COMPLETED = "completed"
    INTERRUPTED = "interrupted"


class FrequencyAnalysisPoint(BaseModel):
    """
    频域分析数据点模型
    
    对应frequency_analysis_data JSON数组中的单个元素，包含：
    - 时间戳信息
    - 睡眠分期结果和置信度
    - 5个频域比例数据（delta, theta, alpha, beta, gamma）
    """
    timestamp: float = Field(..., description="数据点时间戳（Unix时间戳）")
    state: str = Field(..., description="睡眠分期结果（awake, light_sleep, deep_sleep等）")
    confidence: float = Field(..., ge=0.0, le=1.0, description="分期置信度（0-1）")
    
    # 5个频域数据
    delta: float = Field(..., ge=0.0, le=1.0, description="Delta波段比例")
    theta: float = Field(..., ge=0.0, le=1.0, description="Theta波段比例")
    alpha: float = Field(..., ge=0.0, le=1.0, description="Alpha波段比例")
    beta: float = Field(..., ge=0.0, le=1.0, description="Beta波段比例")
    gamma: float = Field(..., ge=0.0, le=1.0, description="Gamma波段比例")

    @validator('delta', 'theta', 'alpha', 'beta', 'gamma')
    def validate_frequency_ratio(cls, v):
        """验证频域比例值在合理范围内"""
        if not 0.0 <= v <= 1.0:
            raise ValueError('频域比例必须在0.0到1.0之间')
        return v

    @validator('confidence')
    def validate_confidence(cls, v):
        """验证置信度值"""
        if not 0.0 <= v <= 1.0:
            raise ValueError('置信度必须在0.0到1.0之间')
        return v


class SleepAnalysisSession(BaseModel):
    """
    睡眠分析会话主模型
    
    对应sleep_analysis_sessions表结构，支持频域比例累积数据存储模式
    """
    # 主键和基础信息
    id: Optional[int] = Field(None, description="自增主键")
    session_id: str = Field(..., description="会话ID，业务主键")
    room_id: str = Field(..., description="房间ID")
    user_id: str = Field(default="default_user", description="用户ID")
    
    # 会话时间信息
    session_start_time: datetime = Field(default_factory=datetime.now, description="会话开始时间")
    last_update_time: datetime = Field(default_factory=datetime.now, description="最后更新时间")
    session_duration_seconds: int = Field(default=0, description="会话总时长（秒）")
    
    # 数据统计信息
    total_data_points: int = Field(default=0, description="总数据点数量")
    first_data_timestamp: Optional[float] = Field(None, description="第一个数据点时间戳")
    last_data_timestamp: Optional[float] = Field(None, description="最后一个数据点时间戳")
    
    # 累积数据存储
    frequency_analysis_data: List[FrequencyAnalysisPoint] = Field(default_factory=list, description="频域分析数据点数组")
    
    # 会话状态和质量指标
    session_status: SessionStatus = Field(default=SessionStatus.ACTIVE, description="会话状态")
    average_confidence: float = Field(default=0.0, ge=0.0, le=1.0, description="平均分期置信度")
    dominant_sleep_stage: str = Field(default="unknown", description="主要睡眠分期")
    
    # 数据质量指标
    signal_quality_score: float = Field(default=0.0, ge=0.0, le=1.0, description="信号质量评分")
    data_completeness_ratio: float = Field(default=0.0, ge=0.0, le=1.0, description="数据完整性比例")

    def add_analysis_point(self, analysis_point: FrequencyAnalysisPoint) -> None:
        """
        添加新的频域分析数据点到会话中
        
        Args:
            analysis_point: 新的频域分析数据点
        """
        self.frequency_analysis_data.append(analysis_point)
        self.total_data_points = len(self.frequency_analysis_data)
        self.last_data_timestamp = analysis_point.timestamp
        self.last_update_time = datetime.now()
        
        # 更新第一个数据点时间戳
        if self.first_data_timestamp is None:
            self.first_data_timestamp = analysis_point.timestamp
        
        # 重新计算统计信息
        self._update_statistics()

    def add_analysis_points(self, analysis_points: List[FrequencyAnalysisPoint]) -> None:
        """
        批量添加频域分析数据点到会话中
        
        Args:
            analysis_points: 频域分析数据点列表
        """
        if not analysis_points:
            return
            
        self.frequency_analysis_data.extend(analysis_points)
        self.total_data_points = len(self.frequency_analysis_data)
        self.last_data_timestamp = max(point.timestamp for point in analysis_points)
        self.last_update_time = datetime.now()
        
        # 更新第一个数据点时间戳
        if self.first_data_timestamp is None and analysis_points:
            self.first_data_timestamp = min(point.timestamp for point in analysis_points)
        
        # 重新计算统计信息
        self._update_statistics()

    def _update_statistics(self) -> None:
        """更新会话统计信息"""
        if not self.frequency_analysis_data:
            return
        
        # 计算平均置信度
        total_confidence = sum(point.confidence for point in self.frequency_analysis_data)
        self.average_confidence = total_confidence / len(self.frequency_analysis_data)
        
        # 计算会话时长
        if self.first_data_timestamp and self.last_data_timestamp:
            self.session_duration_seconds = int(self.last_data_timestamp - self.first_data_timestamp)
        
        # 计算主要睡眠状态
        state_counts = {}
        for point in self.frequency_analysis_data:
            state_counts[point.state] = state_counts.get(point.state, 0) + 1
        
        if state_counts:
            self.dominant_sleep_stage = max(state_counts, key=state_counts.get)
        
        # 计算数据质量指标（基于置信度）
        high_confidence_points = sum(1 for point in self.frequency_analysis_data if point.confidence >= 0.7)
        self.signal_quality_score = high_confidence_points / len(self.frequency_analysis_data) if self.frequency_analysis_data else 0.0
        
        # 数据完整性（假设每秒应该有一个数据点）
        if self.session_duration_seconds > 0:
            expected_points = self.session_duration_seconds
            self.data_completeness_ratio = min(1.0, len(self.frequency_analysis_data) / expected_points)
        else:
            self.data_completeness_ratio = 1.0

    class Config:
        """Pydantic配置"""
        use_enum_values = True
        json_encoders = {
            datetime: lambda v: v.isoformat()
        }


class SessionCreateRequest(BaseModel):
    """创建会话请求模型"""
    session_id: str = Field(..., description="会话ID")
    room_id: str = Field(..., description="房间ID")
    user_id: str = Field(default="default_user", description="用户ID")
    initial_data_points: Optional[List[FrequencyAnalysisPoint]] = Field(default_factory=list, description="初始数据点")


class SessionUpdateRequest(BaseModel):
    """更新会话数据请求模型"""
    session_id: str = Field(..., description="会话ID")
    new_data_points: List[FrequencyAnalysisPoint] = Field(..., description="新增数据点列表")
    session_status: Optional[SessionStatus] = Field(None, description="更新会话状态")


class SessionQueryResponse(BaseModel):
    """会话查询响应模型"""
    success: bool = Field(True, description="查询是否成功")
    message: str = Field("查询成功", description="响应消息")
    session: Optional[SleepAnalysisSession] = Field(None, description="会话数据")
    total_sessions: Optional[int] = Field(None, description="总会话数（分页查询时使用）")


class SessionListResponse(BaseModel):
    """会话列表响应模型"""
    success: bool = Field(True, description="查询是否成功")
    message: str = Field("查询成功", description="响应消息")
    sessions: List[SleepAnalysisSession] = Field(default_factory=list, description="会话列表")
    total_count: int = Field(0, description="总记录数")
    page: int = Field(1, description="当前页码")
    page_size: int = Field(10, description="每页大小")


class SessionStatistics(BaseModel):
    """会话统计信息模型"""
    session_id: str = Field(..., description="会话ID")
    total_duration_seconds: int = Field(..., description="总时长（秒）")
    total_data_points: int = Field(..., description="总数据点数")
    average_confidence: float = Field(..., description="平均置信度")
    dominant_sleep_state: str = Field(..., description="主要睡眠状态")
    signal_quality_score: float = Field(..., description="信号质量评分")
    data_completeness_ratio: float = Field(..., description="数据完整性比例")
    
    # 频域统计
    average_delta: float = Field(..., description="平均Delta波段比例")
    average_theta: float = Field(..., description="平均Theta波段比例")
    average_alpha: float = Field(..., description="平均Alpha波段比例")
    average_beta: float = Field(..., description="平均Beta波段比例")
    average_gamma: float = Field(..., description="平均Gamma波段比例")